查看原文
其他

Android 开发者 | 应用兼容性注意事项

2018-01-13 Google Play 谷歌开发者


由于国内 Android 开发环境的特殊性,兼容性一直是很多开发者极为关注的问题。为此,我们特意请来了负责 Android 在中国兼容性问题的 Google 工程师为大家对一些常见问题做出解答,来看看我的工程师提到了哪些要点吧!


"大家好,我是谷歌的开发技术推广工程师,主要负责 Android 在中国的兼容性问题。我们发现,每次有 Android 新版本发布时,国内有很多应用由于没有遵循最佳开发实践,或使用了依赖于底层非公开 API 的 “黑科技”,而无法直接在新版本上运行,必须做出相当的代码修改来进行兼容。在这篇文章中,我们总结了关于应用开发在兼容性方面的注意事项,希望大家在开发过程中多加注意。"



不要使用私有 API

私有 API 是指 Android 系统内部使用、并未提供公开接口的 API,开发者可能通过 Java 反射等技术来调用这些私有 API。但是,这么做是很危险的:私有 API 没有任何公开文档,必须查看源代码才能理解其行为逻辑。


私有 API 的接口信息、函数签名(包括参数列表和返回值)、行为逻辑都有可能在下个 Android 版本中被大幅修改,甚至 API 本身也可能被删除。这会导致使用私有 API 的应用在新的 Android 版本中无法运行,或运行时产生不符合预期的行为,开发者必须投入相当的研发资源保持其在未来每个 Android 新版本中的适配。


直接使用底层的私有 API 有可能会绕过一些 Android 对用户的安全性和隐私性方面的保护,不但影响用户体验、妨害用户隐私,也很可能会被 Google Play Protect 判定为恶意软件而提示用户卸载应用。


所以,我们强烈建议开发者只使用 Android 公开的 API 进行应用开发。公开 API 有详细的技术文档和支持渠道,未来的 Android 新版本也会保证公开 API 的兼容性(即使有改动,也会在文档中详细阐明)。


如果您有合理的理由,必须使用某个私有 API,请告诉我们!我们很乐意聆听和讨论,并会在充分评估必要性和可行性后,在 Android 系统或 Support Library 中提供方案来满足合理的功能需求。



不要直接调用 dex2oat

从一开始,dex2oat  就被设计为系统内部使用的编译部署工具,Android 从来都未支持过开发者直接调用 dex2oat 的场景。我们会持续而不定期地对这个工具进行优化,而很多时候其行为变更(如:生成的文件及其格式)都是与之前不兼容的。在大多数情况下,标准的类加载器(BaseDexClassLoader / DexClassLoader / PathClassLoader)无法找到或使用由直接调用 dex2oat 生成的文件。


如果您需要从内存中加载 dex 文件,而不愿在存储中留下痕迹,请使用 Android O 中新增的加载器 InMemoryDexClassLoader。



不要注入或篡改 Android Studio 生成的 dex 和 so 文件

Android Studio 生成的 dex 文件虽然有公开的布局格式,但具体内容还是会在运行时被系统在后台进行编译优化。如果您在 dex 文件中写入自定义的内容,很可能这些自定义的写入操作与系统优化发生冲突,以致自定义的内容被擦除或覆盖,甚至导致优化后的 dex 在执行时直接崩溃。


Android Studio 生成的 so 文件包含一些元数据(如 ELF headers 和 section headers),以备动态链接器进行完整性检查。篡改 so 文件并不会带来安全性的提升(很多工具可以重新生成元数据),反而可能导致应用无法在未来的 Android 版本中无法启动(由于动态链接器可能执行更严格的检查)。更多关于 so 文件的要求,请查看以下链接中的文档(会有不定期更新)

https://android.googlesource.com/platform/bionic/+/master/android-changes-for-ndk-developers.md



不要干扰或篡改系统内部加载 dex 的逻辑

Android 系统内部加载 dex 的逻辑比较复杂,会考虑很多因素(如安全性、隐私性等),其具体行为逻辑也可能会在新版本中加以修改。如果您干扰或篡改了 dex 的加载逻辑,不但会增加安全性方面的风险,也很可能在新的系统更新后不再工作,甚至导致应用无法运行。



不要使用 DexFile 类

DexFile 类已经在 Android O 中被废弃。DexFile 在应用开发中的使用暴露了很多问题,导致应用崩溃或错误结果。


比如,当多个类加载器试图使用同一个 DexFile 对象来定义某个类时,Android 系统会抛出 InternalError,其错误信息为 “Attempt to register dex file <filename> with multiple class loaders”。这是因为运行环境将 DexFile 与一些附加的内部状态信息进行关联,而这些内部状态信息不能在类加载器之间进行共享。


所以,请不要在应用代码中再使用 DexFile 类型。



及时升级第三方 SDK

在中国的 Android 生态中,应用经常依赖的第三方 SDK(特别是加固和热修复框架)会有很多直接的 dex 操作,而导致应用在 Android 版本升级时无法正常运行。我们也开始与一些常见的 SDK 提供商合作(并计划覆盖更多),在 Android 新的预览版本中尽早解决兼容性问题。对于应用开发者来说,只需要经常检查第三方 SDK 的升级公告,及时升级至其最新版本,就能解决大部分与其相关的兼容性问题。

看了工程师划的重点,不知您是否有种豁然开朗的感觉呢?面对复杂的中国 Android 开发生态,很多朋友都会遇到一些特殊的问题,为了更好地服务于国内的 Android 开发者,我们会在收集到一定量特定领域的咨询后,为大家带来 Google 工程师的解决建议及规避方法。


您还有哪些难以解决的开发问题呢?欢迎在我们的公众平台留言!



推荐阅读:

Android Oreo 自适应图标 | 中文教学视频

Android 8.0 Oreo 之推送通知的变化 | 中文教学视频

现已推出 Android 8.1 和 Android Oreo Go 版本

重磅登场!中文版 Android 开发教学视频终于来啦!

“□” 表情无法在 Android 设备显示? 快试试 EmojiCompact 表情兼容库

Android 兼容性 | Google Play 开发者 FAQ 特别版


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存